package idalloc

import (
	"sync"

	"gitee.com/851537/gbase"
)

// IdRange ID范围配置
type IdRange struct {
	Min int64 // 最小ID
	Max int64 // 最大ID
}

// Config ID分配器配置
type Config struct {
	Name          string                  // 表名
	Range         IdRange                 // ID范围
	HeapSize      int                     // 堆大小
	GetUnusedIds  func() ([]int64, error) // 获取未使用ID列表的函数
	SetUnusedIds  func(ids []int64) error // 设置未使用ID列表的函数
	GenerateNewId func() (int64, error)   // 生成新ID的函数（可选）

}

// NewConfig 创建新的配置
func NewConfig(name string, idRange IdRange, opts ...gbase.Option[*Config]) *Config {
	config := &Config{
		Name:  name,
		Range: idRange,
	}

	for _, opt := range opts {
		opt(config)
	}

	return config
}

// WithGetUnusedIds 设置获取未使用ID列表的函数
func WithGetUnusedIds(fn func() ([]int64, error)) gbase.Option[*Config] {
	return func(c *Config) {
		c.GetUnusedIds = fn
	}
}

// WithSetUnusedIds 设置保存未使用ID列表的函数
func WithSetUnusedIds(fn func(ids []int64) error) gbase.Option[*Config] {
	return func(c *Config) {
		c.SetUnusedIds = fn
	}
}

// WithGenerateNewId 设置生成新ID的函数
func WithGenerateNewId(fn func() (int64, error)) gbase.Option[*Config] {
	return func(c *Config) {
		c.GenerateNewId = fn
	}
}

// WithPersistSync 设置持久化同步函数
// func WithPersistSync(fn func()) gbase.Option[*Config] {
// 	return func(c *Config) {
// 		c.PersistSync = fn
// 	}
// }

// WithHeapSize 设置批量获取大小
func WithHeapSize(size int) gbase.Option[*Config] {
	return func(c *Config) {
		c.HeapSize = size
	}
}

// WithSyncPeriod 设置同步周期（秒）
// func WithSyncPeriod(period int) gbase.Option[*Config] {
// 	return func(c *Config) {
// 		c.SyncPeriod = period
// 	}
// }

// DefaultMemoryConfig 创建默认的内存存储配置
func DefaultMemoryConfig(name string, idRange IdRange) *Config {
	// 内存存储
	var memoryStore []int64
	var storeMutex sync.RWMutex

	return NewConfig(name, idRange,
		WithGetUnusedIds(func() ([]int64, error) {
			storeMutex.RLock()
			defer storeMutex.RUnlock()
			return memoryStore, nil
		}),
		WithSetUnusedIds(func(ids []int64) error {
			storeMutex.Lock()
			defer storeMutex.Unlock()
			memoryStore = make([]int64, len(ids))
			copy(memoryStore, ids)
			return nil
		}),
		// WithBatchSize(100),
		// WithSyncPeriod(60),
	)
}
